function h_obj = mfindobj(h_parent, varargin);

% MFINDOBJ - find objects using multiple property/value pairs
%
%    H_OBJ = MFINDOBJ(H_PARENT, P1, V1, P2, V2, ...) finds objects
%    residing in the parent object H_PARENT.  Objects  are found by
%    the FINDOBJ command to possess property values matching those
%    specified by the property name/value pairs Pn/Vn.  The object
%    handles found are returned as H_OBJ.
%
%    MFINDOBJ allows Vn to consist of multiple property values in
%    a cell array, so that a variety of objects having different
%    property values can be found simultaneously.  If some property
%    values Vi are not cell arrays, these values are used in all
%    FINDOBJ commands issued.
%
%    Ex 1: H_OBJ = mfindobj(H_FIG, 'on', 'Type', {'uimenu', ...
%          'uicontrol', 'axes'}, 'Tag', {'menu', 'button', 'axis'})
%          returns the object handles of a UIMENU having a Tag value
%          of 'menu', a UICONTROL having a Tag value of 'button',
%          and an AXES having a Tag value of 'axis'.
%
%    Ex 2: H_OBJ = mfindobj(H_FIG, 'off', 'Style', 'pushbutton', ...
%          'String', {'TAG1', 'TAG2', 'TAG3'}) finds all pushbuttons
%          residing on the figure window H_FIG having the Tag values
%          'TAG1', 'TAG2' or 'TAG3'.

% By:   S.C. Molitor (smolitor@med.unc.edu)
% Date: August 31, 1999

% initialize output to prevent MATLAB errors

h_obj = [];

% check input parameters

if (nargin < 3)
   msgbox('Insufficient number of arguments', 'MFINDOBJ Error', 'warn');
   return
elseif (~ishandle(h_parent))
   msgbox('H_PARENT must be a valid object handle', 'MFINDOBJ Error', 'warn');
   return
elseif (isempty(get(h_parent, 'Children')))
   msgbox('H_PARENT must have child objects', 'MFINDOBJ Error', 'warn');
   return
end

% count number of FINDOBJ statements needed

num_find = 0;
prop_name = {};
for j = 2 : 2 : length(varargin)
   
   % store property names to cell array
   % make sure property names are valid
   
   prop_name{end + 1} = varargin{j - 1};
   if (~ischar(prop_name{end}))
      msgbox(sprintf('Property name %d must be a string', length(prop_name)), 'MFINDOBJ Error', 'warn');
      return
   end
   
   % number of FINDOBJs is the length of the shortest property value cell array
   % number of FINDOBJs is one if no property value cell arrays are provided
   
   prop_value = varargin{j};
   if (iscell(prop_value))
      if (num_find <= 1)
         num_find = length(prop_value);
      else
         num_find = min(num_find, length(prop_value));
      end
   else
      if (num_find == 0)
         num_find = 1;
      end
   end
end

% loop through FINDOBJ statements
% construct each FINDOBJ statement from property/value pairs

for i = 1 : num_find
   pair_string = '';
   prop_value = {};
   
   % obtain property values for FINDOBJ statements
   % if property value is cell array, use appropriate element for each FINDOBJ
   
   for j = 2 : 2 : length(varargin);
      if (iscell(varargin{j}))
         prop_value{end + 1} = varargin{j}{i};
      else
         prop_value{end + 1} = varargin{j};
      end
   end
   
   % construct FINDOBJ statements
   
   for j = 1 : min(length(prop_name), length(prop_value))
      pair_string = [pair_string sprintf(', prop_name{%d}, prop_value{%d}', j, j)];
   end
   
   % execute FINDOBJ statements
   % add returned objects to output
   
   h_find = eval(['findobj(h_parent' pair_string ')'], '');
   h_obj = [h_obj h_find'];
end
return
